from flask import Flask, render_template, request, send_from_directory, jsonify, send_file
from flask_cors import CORS # type: ignore
from PIL import Image, ImageEnhance, ImageFilter, ImageOps
import io
import os
from werkzeug.utils import secure_filename
import base64
import time
from io import BytesIO

from function import *  # 导入所有图像处理函数


app = Flask(__name__)
CORS(app)

# 配置上传文件夹和允许的文件类型,处理后的图片存储目录
UPLOAD_FOLDER = 'static/uploads'
PROCESSED_FOLDER = 'static/processed'
ALLOWED_EXTENSIONS = {'png', 'jpg', 'jpeg', 'gif'}
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['PROCESSED_FOLDER'] = PROCESSED_FOLDER
os.makedirs(UPLOAD_FOLDER, exist_ok=True)
os.makedirs(PROCESSED_FOLDER, exist_ok=True)

# 确保上传文件夹存在
if not os.path.exists(UPLOAD_FOLDER):
    os.makedirs(UPLOAD_FOLDER)

# 在文件顶部添加一个全局变量来存储操作历史
operation_history = []

# 添加记录操作的函数
def log_operation(operation, details, original_image_path=None, processed_image_path=None):
    timestamp = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
    operation_history.append({
        'time': timestamp,
        'operation': operation,
        'details': details,
        'original_image': original_image_path,
        'processed_image': f"/{app.config['PROCESSED_FOLDER']}/{processed_image_path}" if processed_image_path else None
    })

def allowed_file(filename):
    """检查文件扩展名是否允许"""
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

def decode_image(image_data):
    """解码base64图片数据"""
    if image_data.startswith('data:image'):
        image_data = image_data.split(',')[1]
    image_bytes = base64.b64decode(image_data)
    image = Image.open(BytesIO(image_bytes))
    return image

def encode_image(image):
    """将PIL图片对象编码为bytes"""
    img_byte_arr = io.BytesIO()
    image.save(img_byte_arr, format='PNG')
    img_byte_arr.seek(0)
    return img_byte_arr

# 登录页面
@app.route('/')
def login():
    return render_template('login.html')

@app.route('/home')
def home():
    return render_template('home.html')

@app.route('/register')
def register():
    return render_template('register.html')

# 图像处理API路由
# 保存原始图片
@app.route('/api/upload', methods=['POST'])
def upload_image():
    file = request.files['image']
    if file:
        filename = file.filename
        file_path = os.path.join(UPLOAD_FOLDER, filename)
        file.save(file_path)
        return jsonify({'filename': filename, 'file_path': file_path})
    return jsonify({"error": "No file uploaded"}), 400


# 处理图片效果（调整大小）
@app.route('/resize', methods=['POST'])
def resize_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        width = int(data['width'])
        height = int(data['height'])
        
        resized_image = image.resize((width, height), Image.Resampling.LANCZOS)
        original_image_path = data.get('original_image_path')  # 获取原图片路径
        processed_image_path = f"processed_image_{int(time.time())}.png"  # 生成处理后图片路径
        log_operation("调整大小", f"宽度: {width}, 高度: {height}", original_image_path, processed_image_path)
        
        # 保存处理后的图片
        with open(os.path.join(app.config['PROCESSED_FOLDER'], processed_image_path), 'wb') as f:
            f.write(encode_image(resized_image).getvalue())
        
        return send_file(encode_image(resized_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


@app.route('/rotate', methods=['POST'])
def rotate_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        angle = int(data['angle'])
        
        rotated_image = image.rotate(angle, expand=True)
        log_operation("旋转", f"角度: {angle}度")
        return send_file(encode_image(rotated_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400



# 处理图片质量调整
@app.route('/api/quality', methods=['POST'])
def adjust_quality():
    data = request.get_json()
    file_path = data.get('file_path')
    quality = int(data.get('quality'))

    try:
        img = Image.open(file_path)
        img_io = io.BytesIO()
        img.save(img_io, 'JPEG', quality=quality)
        img_io.seek(0)
        log_operation("调整质量", f"质量: {quality}")
        return send_file(img_io, mimetype='image/jpeg')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


# 处理亮度调整
@app.route('/api/brightness', methods=['POST'])
def adjust_brightness():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        factor = float(data.get('factor', 1.0))
        
        enhancer = ImageEnhance.Brightness(image)
        adjusted_image = enhancer.enhance(factor)
        log_operation("调整亮度", f"因子: {factor}")
        return send_file(encode_image(adjusted_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


# 处理对比度调整
@app.route('/api/contrast', methods=['POST'])
def adjust_contrast():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        factor = float(data.get('factor', 1.0))
        
        enhancer = ImageEnhance.Contrast(image)
        adjusted_image = enhancer.enhance(factor)
        log_operation("调整对比度", f"因子: {factor}")
        return send_file(encode_image(adjusted_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


# 处理滤镜效果（例如模糊）
@app.route('/api/filter', methods=['POST'])
def apply_filter():
    data = request.get_json()
    file_path = data.get('file_path')
    filter_type = data.get('filter_type')

    try:
        img = Image.open(file_path)

        if filter_type == 'blur':
            img = img.filter(ImageFilter.GaussianBlur(5))
        elif filter_type == 'sharpen':
            img = img.filter(ImageFilter.SHARPEN)
        else:
            return jsonify({"error": "Invalid filter type"}), 400

        img_io = io.BytesIO()
        img.save(img_io, 'JPEG')
        img_io.seek(0)
        log_operation("应用滤镜", f"类型: {filter_type}")
        return send_file(img_io, mimetype='image/jpeg')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


@app.route('/api/upload', methods=['POST'])
def upload_file():
    if 'image' not in request.files:
        return jsonify({'error': '没有文件'}), 400
        
    file = request.files['image']
    if file.filename == '':
        return jsonify({'error': '没有选择文件'}), 400
        
    if file and allowed_file(file.filename):
        try:
            # 处理文件
            filename = secure_filename(file.filename)
            file_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(file_path)
            
            return jsonify({
                'message': '上传成功',
                'filename': filename
            })
        except Exception as e:
            return jsonify({'error': str(e)}), 500
    
    return jsonify({'error': '不支持的文件类型'}), 400

# 添加还原和保存功能的路由
@app.route('/api/restore', methods=['POST'])
def restore():
    """还原原图"""
    data = request.json
    if 'original_image' not in data:
        return jsonify({'error': '找不到原始图片'}), 400
    return jsonify({'image': data['original_image']})

@app.route('/api/flip', methods=['POST'])
def flip_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        direction = data['direction']
        
        if direction == 'horizontal':
            flipped_image = ImageOps.mirror(image)
        else:
            flipped_image = ImageOps.flip(image)
            
        log_operation("翻转", f"方向: {direction}")
        return send_file(encode_image(flipped_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/crop', methods=['POST'])
def crop_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        x = int(data['x'])
        y = int(data['y'])
        width = int(data['width'])
        height = int(data['height'])
        
        cropped_image = image.crop((x, y, x + width, y + height))
        log_operation("裁剪", f"位置: ({x}, {y}) 到 ({x + width}, {y + height})")
        return send_file(encode_image(cropped_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/sharpen', methods=['POST'])
def sharpen_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        
        sharpened_image = image.filter(ImageFilter.SHARPEN)
        log_operation("锐化", "")
        return send_file(encode_image(sharpened_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/blur', methods=['POST'])
def blur_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        
        blurred_image = image.filter(ImageFilter.GaussianBlur(radius=2))
        log_operation("模糊", "")
        return send_file(encode_image(blurred_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/grayscale', methods=['POST'])
def grayscale_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        
        gray_image = ImageOps.grayscale(image)
        log_operation("转换为灰度图像", "")
        return send_file(encode_image(gray_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400

@app.route('/api/equalize', methods=['POST'])
def equalize_image():
    try:
        data = request.get_json()
        image = decode_image(data['image'])
        
        equalized_image = ImageOps.equalize(image)
        log_operation("均衡化", "")
        return send_file(encode_image(equalized_image), mimetype='image/png')
    except Exception as e:
        return jsonify({"error": str(e)}), 400


# 添加获取操作历史的API路由
@app.route('/api/history', methods=['GET'])
def get_history():
    return jsonify(operation_history)



# 删除历史记录的 API 路由
@app.route('/api/delete_history', methods=['DELETE'])
def delete_history():
    index = request.args.get('index', type=int)
    if index is not None and 0 <= index < len(operation_history):
        operation_history.pop(index)  # 删除对应的历史记录
        return jsonify({'success': True})
    return jsonify({'success': False, 'error': '未提供有效的索引'}), 400

# 错误处理
@app.errorhandler(400)
def bad_request(error):
    return jsonify({'error': '请求参数错误'}), 400

@app.errorhandler(500)
def server_error(error):
    return jsonify({'error': '服务器内部错误'}), 500



if __name__ == '__main__':
    app.run(debug=True)
